package intransix.osm.termite.gui.dialog;

import intransix.osm.termite.render.source.SourceLayer;
import intransix.osm.termite.app.maplayer.MapLayer;
import intransix.osm.termite.gui.TermiteGui;
import intransix.osm.termite.app.maplayer.MapLayerManager;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.table.*;
import javax.swing.event.*;
import java.util.*;

/**
 *
 * @author sutter
 */
public class SourceLayerDialog extends javax.swing.JDialog implements TableModelListener {
	
	private final static int LAYER_COLUMN = 0;
	private final static int VISIBLE_COLUMN = 1;

	private TermiteGui gui;
	private MapLayerManager mapLayerManager;
	private DefaultTableModel model;
	private HashMap<Integer,SourceLayer> layerMap = new HashMap<Integer,SourceLayer>();
	
	/**
	 * Creates new form SourceLayerDialog
	 */
	public SourceLayerDialog(TermiteGui gui, MapLayerManager mapLayerManager) {
		super(gui,false);
		this.gui = gui;
		this.mapLayerManager = mapLayerManager;
		initComponents();
				
		model = (DefaultTableModel)sourceTable.getModel();
		model.addTableModelListener(this);
		Object[] row = new Object[2];
		layerMap.clear();
		int index = 0;
		for(MapLayer layer:mapLayerManager.getMapLayers()) {
			if(layer instanceof SourceLayer) {
				row[0] = layer.getName();
				row[1] = layer.isVisible();
				model.addRow(row);
				layerMap.put(index++,(SourceLayer)layer);
			}
		}
	}	
	
	@Override
	public void tableChanged(TableModelEvent e) {
		if(e.getType() == TableModelEvent.UPDATE) {
			int row = e.getFirstRow();
			
			//this shouldn't happen - return with no action
			int lastRow = e.getLastRow();
			if(lastRow != row) {
				System.out.println("Unknown error - multi row edit");
				return;
			}
			
			SourceLayer layer = layerMap.get(row);
			int column = e.getColumn();
			Object value = model.getValueAt(row, column);
			
			if(column == LAYER_COLUMN) {
				layer.setName((String)value);
			}
			else if(column == VISIBLE_COLUMN) {
				layer.setVisible((Boolean)value);
			}
			else {
				return;
			}
		}
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        sourceTable = new javax.swing.JTable();
        closeButton = new javax.swing.JButton();
        newButton = new javax.swing.JButton();
        deleteButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        sourceTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Source Image", "Visible"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.String.class, java.lang.Boolean.class
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }
        });
        sourceTable.getTableHeader().setReorderingAllowed(false);
        jScrollPane1.setViewportView(sourceTable);

        closeButton.setText("Close");
        closeButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                closeButtonActionPerformed(evt);
            }
        });

        newButton.setText("Add");
        newButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newButtonActionPerformed(evt);
            }
        });

        deleteButton.setText("Remove");
        deleteButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 375, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(closeButton)
                        .addGap(50, 50, 50))))
            .addGroup(layout.createSequentialGroup()
                .addGap(80, 80, 80)
                .addComponent(newButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(deleteButton)
                .addGap(91, 91, 91))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 130, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(37, 37, 37)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(newButton)
                    .addComponent(deleteButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 50, Short.MAX_VALUE)
                .addComponent(closeButton)
                .addGap(26, 26, 26))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

	private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed
		setVisible(false);
	}//GEN-LAST:event_closeButtonActionPerformed

	private void newButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newButtonActionPerformed
		SourceLayer sourceLayer = openSourceLayer();
		if(sourceLayer != null) {
			mapLayerManager.addLayer(sourceLayer);
			Object[] row = new Object[2];
			row[0] = sourceLayer.getName();
			row[1] = sourceLayer.isVisible();
			int index = model.getRowCount();
			model.addRow(row);
			layerMap.put(index,sourceLayer);
		}
	}//GEN-LAST:event_newButtonActionPerformed

	private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed
		int index = sourceTable.getSelectedRow();
		if(index > -1) {
			SourceLayer layer = layerMap.get(index);
			mapLayerManager.removeLayer(layer);
			model.removeRow(index);
		}
		else {
			JOptionPane.showMessageDialog(this,"You must select a row to delete.");
		}
	}//GEN-LAST:event_deleteButtonActionPerformed


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton closeButton;
    private javax.swing.JButton deleteButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton newButton;
    private javax.swing.JTable sourceTable;
    // End of variables declaration//GEN-END:variables

	private SourceLayer openSourceLayer() {
		//open image file
		JFileChooser fc = new JFileChooser();
		fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
		java.io.File workingDirectory = gui.getWorkingDirectory();
		if(workingDirectory != null) fc.setCurrentDirectory(workingDirectory);
		int returnVal = fc.showOpenDialog(this);
		if(returnVal == JFileChooser.APPROVE_OPTION) {
			SourceLayer sourceLayer = new SourceLayer();
			java.io.File file = fc.getSelectedFile();
			gui.setWorkingDirectory(fc.getCurrentDirectory());
			boolean success = sourceLayer.loadImage(file);
			if(success) {
				sourceLayer.setActiveState(true);
				sourceLayer.setName(file.getName());
				return sourceLayer;
			}
			else {
				JOptionPane.showMessageDialog(this,"There was an error loading the image.");
				return null;
			}
		}
		else {
			return null;
		}
	}

}
